﻿using System;
using System.Text;

using Mono.Zeroconf;

namespace passitumi
{
	/**
	 * This class is used to broadcast the Passitumi service using the 
	 * Mono.Zeroconf package on a seperate thread.
	 */
	class ServiceBroadcaster
	{
		// The singleton instance of the broadcaster
		private static ServiceBroadcaster instance;

		// The actual service instance
		private RegisterService service;

		// A boolean representing whether or not the service broadcaster is running and whether or not we are actively broadcasting our service
		private bool running = false, broadcasting = true;
		
		// Variables for the service and the client information
		private string serviceName = System.Environment.MachineName + "[" + DateTime.Now + "]";
		private string regType = "_passitumi._tcp";
		private string replyDomain = "local.";
		private short port = 3689;

		// The interval that our signal is re-broadcasted on
		private int interval = 10000;

		/**
		 * Singleton method to retrieve the ONLY instance of the
		 * ServiceBroadcaster object.
		 */
		public static ServiceBroadcaster getInstance()
		{
			if (ServiceBroadcaster.instance == null)
				ServiceBroadcaster.instance = new ServiceBroadcaster();

			return ServiceBroadcaster.instance;
		}
		
		/**
		 * Default constructor
		 */
		private ServiceBroadcaster()
		{
			// Define the Mono.Zeroconf service with appropriate information
			this.service = new RegisterService();
			this.service.Name = serviceName;
			this.service.RegType = regType;
			this.service.ReplyDomain = replyDomain;
			this.service.Port = port;

			// Fill text records (additional information) for our broadcasted service
			TxtRecord txt_record = new TxtRecord();
			txt_record.Add("displayName", passitumi.Properties.Settings.Default.displayName);
			service.TxtRecord = txt_record;
		}

		/**
		 * Start the service.
		 */
		public void start()
		{
			Console.WriteLine("ServiceBroadcaster: Registering client to the network [{0}]", System.Threading.Thread.CurrentThread.ManagedThreadId);
			this.broadcasting = true;
			// Register our service on the network
			this.service.Register();
		}

		/**
		 * Stop the service from running.
		 */
		public void stop()
		{
			Console.WriteLine("ServiceBroadcaster: De-registering service from the network [{0}]", System.Threading.Thread.CurrentThread.ManagedThreadId);
			this.broadcasting = false;
			this.service.Dispose();
		}

		/**
		 * Return the local published service name.
		 */
		public string getLocalServiceName()
		{
			return this.serviceName;
		}
	}
}
